/**
 * All the functions needed to render text on the screen
 *
 * Originally written by: Jonas Strandstedt
 */

#define MAX_NUMBER_OF_MESSAGES 5

char screenMessages[MAX_NUMBER_OF_MESSAGES][100];
int usedMessages = 0;
int fonts[] = {0,0,0,0};

/**
 * initiates text fonts
 */
void initTextFonts() {
	glEnable(GL_TEXTURE_2D);
    glGenTextures(4, fonts); 
	// loading the 4 different sizes of the arial font
	glBindTexture(GL_TEXTURE_2D, fonts[0]);
    glfwLoadTexture2D(OS_FONT_PATH(arial6.tga), GLFW_BUILD_MIPMAPS_BIT);
    glBindTexture(GL_TEXTURE_2D, fonts[1]);
    glfwLoadTexture2D(OS_FONT_PATH(arial8.tga), GLFW_BUILD_MIPMAPS_BIT);
    glBindTexture(GL_TEXTURE_2D, fonts[2]);
    glfwLoadTexture2D(OS_FONT_PATH(arial10.tga), GLFW_BUILD_MIPMAPS_BIT);
    glBindTexture(GL_TEXTURE_2D, fonts[3]);
    glfwLoadTexture2D(OS_FONT_PATH(arial12.tga), GLFW_BUILD_MIPMAPS_BIT);
    glBindTexture(GL_TEXTURE_2D, 0); // Deactivate the texture again
}

/** 
 * Adds a textmessage to the "buffer" to be rendered on the screen
 * @param string msg = The message as a string to be buffered
 */
void textMessageAdd(char msg[]) {
	if (strcmp (screenMessages[usedMessages-1],msg) != 0) {
		if (usedMessages < MAX_NUMBER_OF_MESSAGES) {
			strcpy (screenMessages[usedMessages],msg);
			usedMessages++;
		} else {
			int i = 0;
			while (i<usedMessages-1) {
				strcpy (screenMessages[i],screenMessages[i+1]);
				i++;
			}
			strcpy (screenMessages[i],msg);
		}
		// debugmsg
		printf("add text to screen: \"%s\" usedMessages=%i \n", msg,usedMessages);
	}
}

/**
 * Prints the messages buffered in "screenMessages"
 */
void printMessages() {
	Color theColor;
	theColor.r = 1.0f;
	theColor.g = 1.0f;
	theColor.b = 0.0f;
	
	int y=0;
	while(y<usedMessages) {
		printTextOnScreen(10,y*20+3,10,screenMessages[y],theColor);
		y++;
	}
}

/**
 * Prints text on the screen
 * @param int xPos = The xPosition from the left
 * @param int yPos = The yPosition from the top
 * @param int fontSize = The character size in both height and width, so far the best size is 16
 * @param char msg[] = The text to be printed
 * @param Color theColor = the desired color of the text
 */
void printTextOnScreen(int xPos, int yPos, int fontSize, char msg[], Color theColor) {
	// debugmsg
	//printf("printonscreen: %s=%i\n", msg, (int) strlen(msg));
	int fs = fontSize;
	int m_size = 256;
	int f_size = 16;
	
	if (fs >= 12) {
		// 12PX FONTMAP HAS OVERLAPPING CHARACTERS
		// fs = 12;
		fs = 10;
	} else if (fs >= 10) {
		fs = 10;
	} else if (fs >= 8) {
		fs = 8;
	} else {
		fs = 6;
	}

	glMatrixMode (GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode (GL_MODELVIEW);
	glLoadIdentity();
	
	if (fs >= 12) {
		glBindTexture( GL_TEXTURE_2D, fonts[3] );
	} else if (fs >= 10) {
		glBindTexture( GL_TEXTURE_2D, fonts[2] );
	} else if (fs >= 8) {
		glBindTexture( GL_TEXTURE_2D, fonts[1] );
	} else {
		glBindTexture( GL_TEXTURE_2D, fonts[0] );
	}
	
	// get the window dimensions to properly setup the text-projection
    int width, height;
    glfwGetWindowSize( &width, &height );
	
	glOrtho(0.0, (float) width,- (float) height, 0.0, -30.0, 30.0);
	glTranslatef(0.0, -30.0, 0.0);
	
	glEnable(GL_BLEND);
//	glBlendFunc(GL_ONE, GL_ONE);
	glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR);
	
	// set the color to the incoming color
	glColor3f(theColor.r,theColor.g,theColor.b);
	
	// calculating stuff to prevent too many calculations inside the loop
	float d = (float) f_size / m_size;
	GLfloat dtx = d;
	GLfloat dty = d;
	GLfloat cx = xPos-fs;
	GLfloat cy = -yPos;
	GLfloat cw = f_size;
	GLfloat ch = f_size;
	
	// the position av texture coordinates
	glBegin(GL_QUADS);
	int i = 0;
	while (i<(int)strlen(msg)) {
		
		// Get the current character
		char c = msg[i];
		int index = (int) c;
		
		cx += (float) f_size;
		// if the character is lower case or ! or "
		// then move the character a little to the left
		if (index > 96 && index < 123 || index > 31 && index < 35) {
			cx -= (float) (f_size / 3.2);
		}
		
		int row = index/f_size+1;
		int col = index%f_size;
		
		// find the texture coords
		GLfloat tx = (float) col * d;
		GLfloat ty = -(float) row * d;
		
		// drawing triangles and setting texture coordinates
		glTexCoord2d(tx,ty);			glVertex2f(cx,cy);
		glTexCoord2d(tx+dtx,ty);		glVertex2f(cx+cw,cy);
		glTexCoord2d(tx+dtx,ty+dty);	glVertex2f(cx+cw,cy+ch);
		glTexCoord2d(tx,ty+dty);		glVertex2f(cx,cy+ch);
		
		// debugmsg
		//printf("c=%c nr=%i col=%i row=%i\n ",c,(int)c,col,row);
		
		// adding i so next character gets printed and not the same infinite number of times
		i++;
	}
	glEnd();
	
	// disables blend options and textures 
	glDisable(GL_BLEND);
    glBindTexture(GL_TEXTURE_2D, 0); // Deactivate the texture again
	
}

void printStats(PlayerObject *player1, PlayerObject *player2) {
	char user_message[30];
	int windowHeight, windowWidth;
	glfwGetWindowSize(&windowWidth,&windowHeight);
	Color theColor; theColor.r = 1.0f; theColor.g = 0.0f; theColor.b = 0.0f;
	int player1Textypos = windowHeight / 2 - 70;
	int player2Textypos = windowHeight - 70;
	
	if (player1->isDead>0) {
		sprintf(user_message, "Respawn in %i", PLAYER_RESPAWN_TIME - player1->isDead);
		printTextOnScreen(10,2,10,user_message,theColor);
	} else {
		sprintf(user_message, "HP = %i", player1->life);
		printTextOnScreen(10,2,10,user_message,theColor);
		if (player1->weapon != WEAPON_NONE) {
			sprintf(user_message, "%s", weaponNamesArray[player1->weapon]);
			printTextOnScreen(10,20,10,user_message,theColor);
			sprintf(user_message, "Ammo = %i", player1->ammo);
			printTextOnScreen(10,40,10,user_message,theColor);
		}
	}
	
	if (player2->isDead>0) {
		sprintf(user_message, "Respawn in %i", PLAYER_RESPAWN_TIME - player2->isDead);
		printTextOnScreen(10,windowHeight/2+2,10,user_message,theColor);
	} else {
		sprintf(user_message, "HP = %i", player2->life);
		printTextOnScreen(10,windowHeight/2+2,10,user_message,theColor);
		if (player2->weapon != WEAPON_NONE) {
			sprintf(user_message, "%s", weaponNamesArray[player2->weapon]);
			printTextOnScreen(10,windowHeight/2+20,10,user_message,theColor);
			sprintf(user_message, "Ammo = %i", player2->ammo);
			printTextOnScreen(10,windowHeight/2+40,10,user_message,theColor);
		}
	}
	
	printTextOnScreen(10,player1Textypos,10,player1->identifier,theColor);
	sprintf(user_message,"Score=%i Death=%i",player1->score,player1->death);
	printTextOnScreen(10,player1Textypos+20,10,user_message,theColor);
	printTextOnScreen(10,player2Textypos,10,player2->identifier,theColor);
	sprintf(user_message,"Score=%i Death=%i",player2->score,player2->death);
	printTextOnScreen(10,player2Textypos+20,10,user_message,theColor);
}